﻿#pragma once

#include "MathOperation.h"

namespace ASL
{

    // 机构模型
    class ASL_API Gear
    {
    public:
        // 构造函数
        Gear();

        // 析构函数
        ~Gear();

        // 关联数据列表
        struct Input
        {
            // 机构位置 0~1
            double gearPosition;

            // 转向幅度 -90~+90 deg
            double steerPosition;

            // 刹车幅度 0~1
            double brakePosition;

            // 相对地面高度 m
            double altitudeGL;

            // 姿态角 deg 坐标轴旋转顺序 Y-Z-X [gamma, psi, zeta]
            ASL::Vector eular;

            // 角速度 deg/s 机体系 [X, Y, Z]
            ASL::Vector omega;

            // 速度 m/s 机体系 [X, Y, Z]
            ASL::Vector vBody;

            // 坐标系投影矩阵 导航系>机体系
            ASL::Matrix cN2B;

            // 相对位置坐标 m 机体系 [X, Y, Z]
            ASL::Vector relativeLocation;
        };

        // 地面作用计算函数
        static bool reaction(ASL::Gear &G, ASL::Gear::Input &input);

    public:
        // 机构安装位置 m 结构系 [X, Y, Z]
        ASL::Vector location;

        // 刹车静摩擦系数 -
        double staticCoeff;

        // 轮胎动摩擦系数 -
        double dynamicCoeff;

        // 轮胎滚动摩擦系数 -
        double rollingCoeff;

        // 缓冲器劲度系数 N/m
        double springCoeff;

        // 缓冲器阻尼系数 N/m/s
        double dampingCoeff;

        // 摩擦过渡区间 m/s
        double linearBand;

    public:
        // 坐标系投影矩阵 导航系>局部系
        ASL::Matrix cN2L;

        // 轮胎触地状态 -
        bool onGround;

        // 地面作用力 N 机体系 [X, Y, Z]
        ASL::Vector force;

        // 地面作用力矩 N*m 机体系 [X, Y, Z]
        ASL::Vector torque;

        // 轮胎转向角 deg
        double steerAngle;

        // 轮胎滑移角 deg
        double wheelSlip;
    };

    // 通用三点式起落架模型
    class ASL_API LandingGear
    {
    public:
        // 构造函数
        LandingGear();

        // 析构函数
        ~LandingGear();

        // 参数配置函数
        // 输入 aircraft 飞行器类型 AIRCRAFT_XXX
        // 返回 return 执行状态 -
        bool setup(int aircraft);

        // 初始化函数
        // 输入 stepSize 仿真步长 s
        // 返回 return 执行状态 -
        bool initialize(double stepSize);

        // 单步运行函数
        // 输入 -
        // 返回 return 执行状态 -
        bool step(void);

    public:
        // 输入端口列表
        struct Input
        {
            // 机构位置指令 0/1
            int gearCommand;

            // 前轮转向指令 -1~+1
            double steerCommand;

            // 后轮刹车指令 0~1
            double brakeCommand;

            // 速度 m/s 导航系 [X, Y, Z]
            ASL::Vector vNav;

            // 姿态角 deg 坐标轴旋转顺序 Y-Z-X [gamma, psi, zeta]
            ASL::Vector eular;

            // 角速度 deg/s 机体系 [X, Y, Z]
            ASL::Vector omega;

            // 重心位置 m 结构系 [X, Y, Z]
            ASL::Vector CG;

            // 相对地面高度 m
            double altitudeGL;
        };

        // 输出端口列表
        struct Output
        {
            // 地面反作用力 N 机体系 [X, Y, Z]
            ASL::Vector force;

            // 地面反作用力矩 N*m 机体系 [X, Y, Z]
            ASL::Vector torque;

            // 机构位置 0~1
            double gearPosition;

            // 前轮转向角度 -90~+90 deg
            double steerPosition;

            // 后轮刹车幅度 0~1
            double brakePosition;

            // 轮胎触地状态 - Left && Right
            bool wheelReaction;
        };

        // 参数端口列表
        struct Parameter
        {
            // 初始机构位置 0~1
            double initialPosition;

            // 允许转向角度 0~90 deg
            double steerAngle;

            // 前轮机构模型
            ASL::Gear cGearN;

            // 左轮机构模型
            ASL::Gear cGearL;

            // 右轮机构模型
            ASL::Gear cGearR;
        };

        // 监控端口列表
        struct Watch
        {
        };

    public:
        // 输入端口对象
        ASL::LandingGear::Input input;

        // 输入端口对象
        ASL::LandingGear::Output output;

        // 参数端口对象
        ASL::LandingGear::Parameter parameter;

        // 监控端口对象
        ASL::LandingGear::Watch watch;

    private:
        // 积分器
        ASL::Calculus cGear;
    };

}